﻿////////////////////////////////////////////////////////////////
///
/// File: SimpleTmpExp.cs
/// Author: Lucio Davide Spano
/// Last update: 27 July 2012
/// Description: This class represent a generic ground term.
///              It is possible to define a concrete one 
///              implementing a delegate class (ExpContent)
/// To do: 
/// ------------------------------------------------------------
/// Copyright (c) 2012 Lucio Davide Spano 
///                     (lucio.davide.spano@isti.cnr.it)
/// 
/// The use and distribution terms for this software are 
/// contained in the file named license.txt, which can be found 
/// in the root of this distribution.
/// By using this software in any fashion, you are agreeing to 
/// be bound by the terms of this license.
///
/// You must not remove this notice, or any other, from this
/// software.
/// ------------------------------------------------------------
////////////////////////////////////////////////////////////////

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace GestIT
{
    public class SimpleTmpExp : TmpExp
    {
        public ExpContent Content { get; set; }
        public Token Token { get; set; }

        public SimpleTmpExp()
        {
            this.type = ExpType.Simple;
        }

        public SimpleTmpExp(ExpContent content)
            : this()
        {
            this.Content = content;
        }

        public override bool Accepts(ExpEventArgs args)
        {
            if (State != ExecState.Enabled)
            {
                return false;
            }
            if (Content != null)
            {
                return Content.Accepts(args, Token);
            }
            return false;
        }

        public bool Consume(ExpEventArgs args)
        {
            if (Content != null)
            {
                bool toRet = Content.Consume(args, Token);
                if (toRet)
                {
                    this.SetExectState(ExecState.Completed, Token);
                    RaiseCompleted(this, args, Token);
                }
                else
                {
                    this.SetExectState(ExecState.Error, Token);
                    RaiseError(this, args, Token);
                }
                RaiseOnStateChanged(this, args, Token);

                if (this.Iterative)
                {
                    this.SetExectState(ExecState.Enabled, Token);
                }

                return toRet;
            }

            return false;
        }

        public void Invalidate(ExpEventArgs args)
        {
            this.SetExectState(ExecState.Error, Token);
            RaiseOnStateChanged(this, args, Token);
            RaiseError(this, args, Token);

            if (this.Iterative)
            {
                this.SetExectState(ExecState.Enabled, Token);
            }
        }

        public void NotAccepted(ExpEventArgs args)
        {
            this.RaiseOnNotAcceptedToken(this, args, Token);
        }

        public override void SetExectState(ExecState state, Token token)
        {
            base.SetExectState(state, token);
            switch (state)
            {
                case ExecState.Completed: goto case ExecState.Performing;
                case ExecState.Enabled: goto case ExecState.Performing;
                case ExecState.Performing:
                    this.Token = token;
                    break;

                default:
                    //this.Token = null;
                    break;
            }
        }
    }
}
